package de.vibes.model;

import java.util.Random;

import org.apache.commons.configuration.ConfigurationException;
import org.neodatis.odb.ODB;
import org.neodatis.odb.ODBFactory;
import org.neodatis.odb.Objects;
import org.neodatis.odb.core.query.IQuery;
import org.neodatis.odb.core.query.criteria.Where;
import org.neodatis.odb.core.query.nq.SimpleNativeQuery;
import org.neodatis.odb.impl.core.query.criteria.CriteriaQuery;

import de.vibes.controller.Configuration;

/*****************************************************************
 * Von dieser Klasse werden alle Objekte in dem Model abgeleitet, da hier die
 * Persistence und die Id-Vergabe realisiert sind
 * 
 * @author Igor
 * 
 *****************************************************************/
public abstract class AbstractObject {

	private long id;

	public void setId(long id) {
		this.id = id;
	}

	public long getId() {
		return id;
	}

	/*******************************************************************************
	 * Konstructor. Es wird ein Id erstellt, der in der Persistence nicht
	 * existiert.
	 * 
	 * @throws ConfigurationException
	 *             wenn die DB-Datei nicht gefunden wird.
	 *******************************************************************************/
	public AbstractObject() throws ConfigurationException {
		Random rand = new Random();
		long tempId = rand.nextLong();
		ODB odb = ODBFactory.open(Configuration.getDBFilename());
		IQuery query = new CriteriaQuery(AbstractObject.class, Where.equal(
				"id", tempId));
		Objects<AbstractObject> objects = odb.getObjects(query);
		while (objects.size() > 0) {
			tempId = rand.nextLong();
			query = new CriteriaQuery(AbstractObject.class, Where.equal("id",
					tempId));
			objects = odb.getObjects(query);
		}
		setId(tempId);
		odb.close();
	}

	/************************************************************************
	 * Diese Methode speichert den Objekt in DB
	 * 
	 * @throws ConfigurationException
	 ***********************************************************************/
	public void save() throws ConfigurationException {
		
		ODB odb = ODBFactory.open(Configuration.getDBFilename());
		//Nach einem Objekt mit dasselber Id suchen
		IQuery query = new CriteriaQuery(AbstractObject.class, Where.equal(
				"id", this.id));
		SimpleNativeQuery snq = new SimpleNativeQuery(){
			public boolean match(AbstractObject obj){
				return (obj.getId() == id) ;
			}
		};
		Objects<AbstractObject> objects = odb.getObjects(snq);
		if (objects.size()>0) {
			//Diesen Objekt laden
			AbstractObject tempObj = objects.getFirst();
			//Die Inhalte ersetzen
			tempObj.reload(this);
			//In ODB speichern.
			odb.store(tempObj);
		}else{
			odb.store(this);
		}
		odb.close();
	}

	/************************************************************************
	 * Mit dieser Methode werden alle Inhalte des Objekts durch die Inhalte von
	 * source ersetzt. Diese Methode muss von je. Klasse implementiert werden,
	 * damit das Speichern reibungslos abläuft.
	 * 
	 * @param source AbstractObject
	 ***********************************************************************/
	public abstract void reload(AbstractObject source);

}
